package googleearthdownloader;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Stack;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ProxySystem {
	private Vector<String> ip;
	private Vector<Integer> port;
	private int position;
	private String listFileName;
	private SystemLog systemLog;
	private URL proxyListUrl;
	private BufferedWriter proxilistWriter; 
	
	public ProxySystem(String listFileName, SystemLog systemLog, boolean downloadNewProxys){
		this.listFileName = listFileName;
		this.systemLog = systemLog;
		ip= new Vector<String>();
		port= new Vector<Integer>();
		position=0;
		if(downloadNewProxys){
			try {
				downloadProxyList();
			} catch (IOException e) {
				systemLog.log("Could not download Proxylist",SystemLog.DEBUG_INFO_MESSAGE);
				e.printStackTrace();
			}
		}
		
		readFile();
	}
	
	private void downloadProxyList() throws IOException{
		proxyListUrl = new URL("http://gatherproxy.com/embed");
	    BufferedReader in = new BufferedReader(new InputStreamReader(proxyListUrl.openStream()));

	    String line;
	    StringBuffer sb = new StringBuffer();

	    while ((line = in.readLine()) != null){
	    	sb.append(line);
	    }

	    in.close();
	    
	    String homepage = sb.toString();
	
	    Pattern ippattern = Pattern.compile("\\d{1,3}\\.{1}\\d{1,3}\\.{1}\\d{1,3}\\.{1}\\d{1,3}");
	    Pattern portpattern = Pattern.compile("(?<=\"PROXY_PORT\":\")\\d+");
	    
	    Matcher ipmatcher = ippattern.matcher(homepage);
	    Matcher portmatcher = portpattern.matcher(homepage);
	    
	    
	    
	    int q =0;
	    
	    while(ipmatcher.find() && portmatcher.find()){
	    	q++;
	    }
	    
	    ipmatcher.reset();
	    portmatcher.reset();
	    
	    String[] adresses = new String[q];
	    String[] ports = new String[q];
	    
	    q=0;
	    
	    while(ipmatcher.find() && portmatcher.find()){
	    	adresses[q] = ipmatcher.group();
	    	ports[q] = portmatcher.group();
	    	q++;
	    }
	    
	 
	  
	    proxilistWriter = new BufferedWriter(new FileWriter(listFileName,true));
	    
	    for(int i =0;i<adresses.length;i++){
	    	proxilistWriter.append(adresses[i]+":"+ports[i]);
	    	proxilistWriter.newLine();
	 		systemLog.log("added to proxylistfile: "+adresses[i]+":"+ports[i],SystemLog.DEBUG_INFO_MESSAGE);
	    }
	   
		proxilistWriter.close();
	    
	}
	
	public synchronized Proxy nextProxy() {
		
		position++;
		// Back to Start of List
		if (position >= ip.size()){
			position=0;
		}
		
		return new Proxy(Proxy.Type.SOCKS,new InetSocketAddress(getIP(),getPort()));
	}
	
	public int getNumerOfProxys(){
		return ip.size();
	}
	
	private String getIP() {
		return ip.elementAt(position);
		
	}
	
	private Integer getPort() {
		return port.elementAt(position);
	}

	private void readFile () {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(new File(listFileName)));
            String line = null;
            while((line = br.readLine()) != null) {
                // Ganze Zeile:
            	//TODO systemLog.log("Line form Proxylist read: "+line,SystemLog.DEBUG_INFO_MESSAGE); 
            	if(line.contains(":")){
            		 String[] parts = line.split(":");
                     //TODO systemLog.log("IP: " + parts[0],SystemLog.DEBUG_INFO_MESSAGE);
                     //TODO systemLog.log("Port: " + parts[1],SystemLog.DEBUG_INFO_MESSAGE);
                     ip.add(parts[0]);
                     port.add(new Integer(parts[1]));
            	}
            }
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        } finally {
            if(br != null) {
                try {
                    br.close();
                } catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }
	}
}